home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 24
/
Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso
/
Aminet
/
dev
/
c
/
AmiVoGL_MDEV.lha
/
drivers
/
ibmpc
/
cgaline.asm
< prev
next >
Wrap
Assembly Source File
|
1991-07-18
|
5KB
|
353 lines
TITLE CGALINE - Fast line drawing routine.
NAME CGALINE
PAGE 55,132
COMMENT $
Name: CGALINE
Function: Draw a line in 640x200 2-color mode
Caller: Microsoft C:
void cgaline(x1, y1, x2, y2, n);
int x1, y1, x2, y2; /* pixel co-ords */
int n; /* pixel value */
$
; Stack frame addressing - LARGE CODE MODEL
ARGx1 EQU word ptr [bp+6]
ARGy1 EQU word ptr [bp+8]
ARGx2 EQU word ptr [bp+10]
ARGy2 EQU word ptr [bp+12]
ARGn EQU byte ptr [bp+14]
VARleafincr EQU word ptr [bp-6]
VARincr1 EQU word ptr [bp-8]
VARincr2 EQU word ptr [bp-10]
VARroutine EQU word ptr [bp-12]
ByteOffsetShift EQU 3 ; Used to convert pixels to byte offset
DGROUP GROUP CGAA_DATA
EXTRN cgapaddr:far
CGAA_TEXT SEGMENT byte public 'CODE'
ASSUME cs:CGAA_TEXT,ds:DGROUP
PUBLIC _cgaline
_cgaline PROC far
push bp ; Set up stack frame
mov bp,sp
sub sp,12 ; Stack space for local variables
push si
push di
mov si,2000h ; Increment for video buffer interleave
mov di,80-2000h ; Increment for last to first interleave
; check for vertical line
mov cx,ARGx2
sub cx,ARGx1
jz VertLine
; force x1 < x2
jns L01 ; jump if x2 > x1
neg cx ; CX = x1 - x2
mov bx,ARGx2; exchange x1 and x2
xchg bx,ARGx1
mov ARGx2,bx
mov bx,ARGy2; exchange y1 and y2
xchg bx,ARGy1
mov ARGy2,bx
; calc dy = abs(y2 - y1)
L01:
mov bx,ARGy2
sub bx,ARGy1; BX = y2 - y1
jnz L02
jmp HorizLine
L02:
jns L03
neg bx ; BX = y1 - y2
neg si ; negate increment for buffer interleave
neg di
xchg si,di
; select appropriate routine for slope of line
L03:
mov VARleafincr,di; save increment for buffer interleave
mov VARroutine,offset LoSlopeLine
cmp bx,cx
jle L04 ; jump if dy <= dx (slopr <= 1)
mov VARroutine,offset HiSlopeLine
xchg bx,cx ; exchange dy and dx
; calc initial decision variable and increments
L04:
shl bx,1 ; BX = 2 * dy
mov VARincr1,bx ; incr1 = 2 * dy
sub bx,cx
mov di,bx ; DI = d = 2*dy - dx
sub bx,cx
mov VARincr2,bx ; incr2 = 2*(dy - dx)
; calc first pixel address
push cx ; preserve the register
mov ax,ARGy1 ; ax = y
mov bx,ARGx1 ; bx = x
call cgapaddr ; ah = bit mask
; es:bx -> buffer
; CL = # bits to shift left
mov al,ARGn ; AL = unshifted pixel value
shl ax,cl ; AH = bitmask in proper position
; AL = pixel value in proper position
mov dx,ax ; DH = bitmask
; DL = pixel value
not dh ; DH = inverse bitmask
pop cx
inc cx
test bx,2000h ; set zero flag if BX in 1st interleave
jz L05
xchg si,VARleafincr ; exchange increament
; values if 1st pixel lies in 1st interleave
L05: jmp VARroutine ; Jump to the appropiate routine for slope
; routine for verticle lines
VertLine:
mov ax,ARGy1
mov bx,ARGy2
mov cx,bx
sub cx,ax
jge L31
neg cx
mov ax,bx
L31:
inc cx
mov bx,ARGx1
push cx
call cgapaddr
mov al,ARGn
shl ax,cl
not ah
pop cx
test bx,si
jz L32
xchg si,di
L32:
test al,al
jz L34
L33:
or es:[bx],al
add bx,si
xchg si,di
loop L33
jmp short L35
L34:
and es:[bx],ah
add bx,si
xchg si,di
loop L34
L35:
jmp Lexit
; routine for horizontal line
HorizLine:
mov ax,ARGy1
mov bx,ARGx1
call cgapaddr
mov di,bx
mov dh,ah
not dh
mov dl,0FFh
shl dh,cl
not dh
mov cx,ARGx2
and cl,7
xor cl,7
shl dl,cl
; determine byte offset of first and last pixel in line
mov ax,ARGx2
mov bx,ARGx1
mov cl,ByteOffsetShift
shr ax,cl
shr bx,cl
mov cx,ax
sub cx,bx
; propagate pixel value throughout one byte
mov bx,offset DGROUP:PropagatedPixel
mov al,ARGn
xlat
; set pixels in leftmost byte of line
or dh,dh
js L43
or cx,cx
jnz L42
and dl,dh
jmp short L44
L42:
mov ah,al
and ah,dh
not dh
and es:[di],dh
or es:[di],ah
inc di
dec cx
; draw remainder of the line
L43:
rep stosb
; set pixels in rightmost byte of line
L44:
and al,dl
not dl
and es:[di],dl
or es:[di],al
jmp Lexit
; routine for dy >= dx (slope <= 1)
LoSlopeLine:
L10:
mov ah,es:[bx]
L11:
and ah,dh
or ah,dl
ror dl,1
ror dh,1
jnc L14
; bit mask not shifted out
or di,di
jns L12
add di,VARincr1
loop L11
mov es:[bx],ah
jmp short Lexit
L12:
add di,VARincr2
mov es:[bx],ah
add bx,si
xchg si,VARleafincr
loop L10
jmp short Lexit
; bit mask shifted out
L14:
mov es:[bx],ah
inc bx
or di,di
jns L15
add di,VARincr1
loop L10
jmp short Lexit
L15:
add di,VARincr2
add bx,si
xchg si,VARleafincr
loop L10
jmp short Lexit
; routine for dy > dx (slope > 1)
HiSlopeLine:
L21:
and es:[bx],dh
or es:[bx],dl
add bx,si
xchg si,VARleafincr
L22:
or di,di
jns L23
add di,VARincr1
loop L21
jmp short Lexit
L23:
add di,VARincr2
ror dl,1
ror dh,1
cmc
adc bx,0
loop L21
Lexit:
pop di
pop si
mov sp,bp
pop bp
ret
_cgaline ENDP
CGAA_TEXT ENDS
CGAA_DATA SEGMENT word public 'DATA'
PropagatedPixel DB 00000000b ;0
DB 11111111b ;1
CGAA_DATA ENDS
END